/**
 * 
 */
package due.pc.pcshoot;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.BoundCamera;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.primitive.Line;
import org.anddev.andengine.entity.primitive.Rectangle;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.shape.Shape;
import org.anddev.andengine.ui.activity.BaseGameActivity;

import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import due.pc.pcshoot.control.Objektiv;
import due.pc.pcshoot.control.OnScreenControl;
import due.pc.pcshoot.control.OnScreenLogger;
import due.pc.pcshoot.control.Player;
import due.pc.pcshoot.control.PlayerScene;
import due.pc.pcshoot.entity.Ball;
import due.pc.pcshoot.entity.Canon;
import due.pc.pcshoot.entity.Helicopter;
import due.pc.pcshoot.entity.IEnemy;
import due.pc.pcshoot.gamelogic.BallLogicHandler;
import due.pc.pcshoot.gamelogic.CanonLogicHandler;
import due.pc.pcshoot.gamelogic.HelicopterLogicHandler;
import due.pc.pcshoot.gamelogic.ObjectiveLogicHandler;
import due.pc.pcshoot.level.Level;
import due.pc.pcshoot.level.LevelLoader;
import due.pc.pcshoot.sensor.MotionDetector2;

/**
 * @author manhhung.vu
 *
 */
public class MainActivity extends BaseGameActivity
{
	//===============================================================/
	//Constants
	//===============================================================/
	public static final boolean PLAY_WITH_PICO_PROJECTOR = true;
	
	
	public static final int CAMERA_WIDTH = 800;
	public static final int CAMERA_HEIGHT = 480;
	
	public static final int CAMERA_CENTERX = CAMERA_WIDTH / 2;
	public static final int CAMERA_CENTERY = CAMERA_HEIGHT / 2;
	
	public static final int VIEW_WIDTH = CAMERA_WIDTH + 480;
	public static final int VIEW_HEIGHT = CAMERA_HEIGHT + 240;
	
	public static final int CAMERA_VIEW_DIFF_WIDTH = VIEW_WIDTH - CAMERA_WIDTH;
	public static final int CAMERA_VIEW_DIFF_HEIGHT = VIEW_HEIGHT - CAMERA_HEIGHT;
	
	public static final int VIEW_X = -CAMERA_VIEW_DIFF_WIDTH / 2;
	public static final int VIEW_Y = -CAMERA_VIEW_DIFF_HEIGHT / 2;
	
	
	//===============================================================/
	//Fields
	//===============================================================/
	private BoundCamera mCamera;
	private Scene mScene;
	
	private OnScreenLogger mOnScreenLogger;
	private OnScreenControl mOnScreenControl;
	
	private Canon mCanon;
	private Objektiv mObjektiv;
	
	private IEnemy[] mEnemies;
	private Level mLevel;
	
	private MotionDetector2 mMotionDetector2 = new MotionDetector2(PLAY_WITH_PICO_PROJECTOR);
	
	private Player mPlayer;
	private PlayerScene mPlayerScene;


	//===============================================================/
	//Override Methods
	//===============================================================/
	
	/* (non-Javadoc)
	 * @see org.anddev.andengine.ui.IGameInterface#onLoadComplete()
	 */
	@Override
	public void onLoadComplete() {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.anddev.andengine.ui.IGameInterface#onLoadEngine()
	 */
	@Override
	public Engine onLoadEngine() {
		
		mCamera = new BoundCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);

		mCamera.setBounds(
				VIEW_X - 5, VIEW_X + VIEW_WIDTH + 10, 
				VIEW_Y - 5, VIEW_Y + VIEW_HEIGHT + 10);
		mCamera.setBoundsEnabled(true);
		
		return new Engine(
				new EngineOptions(
					true, 
					ScreenOrientation.LANDSCAPE, 
					new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), 
					mCamera).setNeedsSound(true));
	}

	/* (non-Javadoc)
	 * @see org.anddev.andengine.ui.IGameInterface#onLoadResources()
	 */
	@Override
	public void onLoadResources() 
	{
		OnScreenControl.registerMultitouchController(mEngine, this);
		
		mOnScreenLogger = new OnScreenLogger(mEngine, this);
		
		
		mObjektiv = Objektiv.createObjective(
				CAMERA_CENTERX - Objektiv.OBJECTIVE_WIDTH / 2, 
				CAMERA_HEIGHT * 2 / 3, 
				mEngine, this);
//		mObjektiv.setZIndex(Integer.MIN_VALUE);
		

//		mOnScreenControl = OnScreenControl.createOnScreenControl(
//				CAMERA_WIDTH - OnScreenControl.CONTROL_WIDTH - 30, CAMERA_HEIGHT - OnScreenControl.CONTROL_HEIGHT - 30, 
//				mEngine, this, OnScreenControl.newVelocityChangeOnScreenControlListener(objektivPhysicsHandler));
		
		mLevel = LevelLoader.loadLevel("level_1.xml", mEngine, this);
		mEnemies = mLevel.getEnemies();
		
		mOnScreenLogger.applyArrowsLogicHandler(mEnemies);
		
		mCanon = Canon.createCanon(
				CAMERA_CENTERX - Canon.CANON_WIDTH / 2, 
				VIEW_HEIGHT - Canon.CANON_HEIGHT - 80, 
				mEngine, this);
		mCanon.setShotAmong(mLevel.getShots());

		mPlayer = new Player(3);
		mPlayerScene = new PlayerScene(mEngine, mCamera, mPlayer);

		
		Ball.preload(5, mEngine, this);
	}

	/* (non-Javadoc)
	 * @see org.anddev.andengine.ui.IGameInterface#onLoadScene()
	 */
	@Override
	public Scene onLoadScene() 
	{		
		mScene = new Scene();
		drawBackgroundGrid();
		

		Shape ground = new Rectangle(VIEW_X, VIEW_Y + VIEW_HEIGHT - 70, VIEW_WIDTH, 100);
		ground.setColor(0.5f, 0.5f, 0.5f);
		mScene.attachChild(ground);	

		
		for (IEnemy enemy : mEnemies) 
		{
			if (enemy instanceof Helicopter) {
				new HelicopterLogicHandler(ground, (Helicopter) enemy, mOnScreenLogger, mScene, mEngine, this);
			}
		}
		
		
		new CanonLogicHandler(mCanon, mObjektiv, mScene);
		
		new BallLogicHandler(
				mCanon, mObjektiv,
				mPlayer, mOnScreenLogger,
				mEnemies, mScene, mEngine, this);

		
		mOnScreenLogger.registerOnParent(mScene);
		mOnScreenLogger.applyFollowedObjects(mPlayer, mCanon);
		
		mCamera.setChaseEntity(mObjektiv);
		new ObjectiveLogicHandler(mObjektiv, mScene, mMotionDetector2);
		

		
		return mScene;
	}
	
	//===============================================================/
	//Own Methods
	//===============================================================/
	private void drawBackgroundGrid()
	{
		mScene.setBackground(new ColorBackground(0.255f, 0.000f, 0.000f));
//		scene.setBackground(new ColorBackground(0.09804f, 0.6274f, 0.8784f));
		
		Rectangle recBG = new Rectangle(VIEW_X, VIEW_Y, VIEW_WIDTH, VIEW_HEIGHT);
		recBG.setColor(0.09804f, 0.6274f, 0.8784f);
		mScene.attachChild(recBG);
		
		for (int i = VIEW_X / 64; i * 64 < VIEW_WIDTH; i++)
		{
			Line line = new Line(64 * i, VIEW_Y, 64 * i, VIEW_HEIGHT);
			line.setColor(0.5f, 0.5f, 0.5f);
			mScene.attachChild(line);
		}
		
		for (int i = VIEW_Y / 64; i * 64 < VIEW_HEIGHT; i++)
		{
			Line line = new Line(VIEW_X, i * 64, VIEW_WIDTH, i * 64);
			line.setColor(0.5f, 0.5f, 0.5f);
			mScene.attachChild(line);
		}
	}
	
	//===============================================================/
	//Orientation Workaround
	//===============================================================/
	private SensorManager mSensorManager;
//	private OrientationData mOrientationData = new OrientationData(Surface.ROTATION_0);
	
	@Override
	protected void onCreate(Bundle pSavedInstanceState) 
	{		
		super.onCreate(pSavedInstanceState);
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
	}
	
	@Override
	protected void onResume() 
	{
		super.onResume();
		
		mSensorManager.registerListener(
				mMotionDetector2,
				mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
				SensorManager.SENSOR_DELAY_GAME);
		
		mSensorManager.registerListener(
				mMotionDetector2,
				mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
				SensorManager.SENSOR_DELAY_GAME);

	}

	@Override
	protected void onStop() 
	{
		mSensorManager.unregisterListener(mMotionDetector2);
		super.onPause();
	}
}
